package rocketman;
/*
Copyright (C) <year> <name of author>

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

import java.util.*;

public class Game extends JPanel implements ActionListener {
    String prefix = "./pics/";
    Dimension d;
    Font smallfont = new Font("Helvetica", Font.BOLD, 14);

    FontMetrics fmsmall, fmlarge;
    double mapy = 0;
    double mapx = 0;
    double activationPixel = 0;
    int levelnumber = 1;
    private int SCREENWIDTH = 800;
    private int SCREENHEIGHT = 600;
    private int spritecount = 3;
    Player player = new Player(400, 450);
    final static LinkedList<Enemy> enemies = new LinkedList<Enemy>();
    final static LinkedList<Bullet> bullets = new LinkedList<Bullet>();
    final static LinkedList<Bullet> friendlybullets = new LinkedList<Bullet>();
    final static LinkedList<Sprite> sprites = new LinkedList<Sprite>();
    final static LinkedList<Sprite> codecs = new LinkedList<Sprite>(); 
    static AIengine aiengine = new AIengine();
    static Room room;
    AIPlayerStateMove playerstate = new AIPlayerStateMove(levelnumber,0);
 
    final int blocksize = 60;
    final int mapw = 13;
    final int maph = 10;
    final int nrofblocks = 13;
    final int scrsize = nrofblocks;//NOTE* blocksize;
    Image bg1,bg2,bg3, tile1, tile2, tile3, explosion1;
    final short leveldata[] =
    { 
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  1,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
    };
    final short leveldata2[] =
    { 
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 1 , 1,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
      0, 0 , 0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  
    };
    short[] screendata;
    Timer timer;
    LevelStateLevel levelstate = new LevelStateLevel(levelnumber);

    public Game() {

        GetImages();
	room = new Room1(enemies,aiengine);
    	//enemies.add(new EnemyPowerup1(0,0, "powerup64x64-1.png", aiengine));
    	//enemies.add(new EnemyRocket(10,10, "rocket20x20-1.png", player.getx(),player.gety(),8,aiengine));
    	//bullets.add(new BulletTargetted(300,100, "bullet16x16-1.png",100,200));
	//bullets.get(0).setdx(-2);
        addKeyListener(new TAdapter());
        screendata = new short[nrofblocks * nrofblocks];
//        mazecolor = new Color(5, 100, 5);
        setFocusable(true);

        d = new Dimension(800, 600);
    	//player = playerstate.initPlayer(0,400,400);
	player.setFriendlyBullets(friendlybullets);
        setBackground(Color.black);
        setDoubleBuffered(true);
        timer = new Timer(40, this);
        timer.start();

	levelstate.setData(enemies,sprites,aiengine, room, codecs,spritecount);
	//AIPlayerStateMove playerstate = new AIPlayerStateMove(levelnumber);
    //Thread thread = new Threa(aiengine);
    //thread.start();   
        	
    }



    public void addNotify() {
        super.addNotify();
        GameInit();
    }

    public void DrawPlayer(Graphics2D g2d) {
           g2d.drawImage(player.getImage(), player.getx(), player.gety(), this);
    }
    public void DrawEnemy(Graphics2D g2d, Enemy enemy) {//NOTE1: -mapx only use
           g2d.drawImage(enemy.getImage(), enemy.getx()-(int)mapx, enemy.gety(), this);
    }

    public void DrawEnemies(Graphics2D g2d) {
	for (int i= 0; i < enemies.size(); i++) 
		DrawEnemy(g2d, enemies.get(i));
    }
    public void MoveEnemies() {
	for (int i= 0; i < enemies.size(); i++) {
		if (enemies.get(i).getx() > SCREENWIDTH || enemies.get(i).gety() > SCREENHEIGHT) {
			enemies.remove(i);
		}
		enemies.get(i).move();
	}
    }
    public void MoveEnemiesLevel2() {
	for (int i= 0; i < enemies.size(); i++) {
		if (enemies.get(i).gety() > SCREENHEIGHT) {
			enemies.remove(i);
		}
		enemies.get(i).move();
	}
    }
    public void EnemiesShoot(LinkedList<Bullet> bullets) {
	for (int i= 0; i < enemies.size(); i++) 
		enemies.get(i).shoot(bullets,player);
    }
    public void EnemiesShootEnemies(LinkedList<Enemy> enemies) {
	for (int i= 0; i < enemies.size(); i++) 
		enemies.get(i).shootenemy(enemies,player);
    }
    public void SpritesShoot(LinkedList<Bullet> bullets) {
	for (int i= 0; i < sprites.size(); i++) 
		sprites.get(i).shoot(bullets,player);
    }
    public void SpritesShootEnemies(LinkedList<Enemy> enemies) {
	for (int i= 0; i < sprites.size(); i++) 
		sprites.get(i).shootenemy(enemies,player);
    }
    public void DrawSprites(Graphics2D g2d) {
	for (int i= 0; i < sprites.size(); i++) 
		DrawSprite(g2d, sprites.get(i));
    }
    public void MoveSprites() {
	for (int i= 0; i < sprites.size(); i++) {
		if (sprites.get(i).getx() > SCREENWIDTH || sprites.get(i).gety() > SCREENHEIGHT) {
			sprites.remove(i);
		}
		sprites.get(i).move();
	}
    }
    public void DrawSprite(Graphics2D g2d, Sprite sprite) {
           g2d.drawImage(sprite.getImage(), sprite.getx(), sprite.gety(), this);
    }    
    public void DrawBullet(Graphics2D g2d, Bullet bullet) {
           g2d.drawImage(bullet.getImage(), bullet.getx(), bullet.gety(), this);
    }
    public void DrawBulletLevel2(Graphics2D g2d, Bullet bullet) {
           g2d.drawImage(bullet.getImage(), bullet.getx() - (int)mapx, bullet.gety(), this);
    }

    public void DrawCodecs(Graphics2D g2d) {
	for (int i= 0; i < codecs.size(); i++) 
		DrawSprite(g2d, codecs.get(i));
    }
    public void DrawBullets(Graphics2D g2d) {
	for (int i= 0; i < bullets.size(); i++) 
		DrawBullet(g2d, bullets.get(i));
    }
    public void DrawBulletsLevel2(Graphics2D g2d) {
	for (int i= 0; i < bullets.size(); i++) 
		DrawBulletLevel2(g2d, bullets.get(i));
    }
    public void MoveBullets() {
	for (int i= 0; i < bullets.size(); i++) {
		bullets.get(i).move();
		if (bullets.get(i).getx() > SCREENWIDTH || bullets.get(i).gety() > SCREENHEIGHT) {
			bullets.remove(i);
		}
	}
    }
    public void MoveBulletsLevel2() {
	for (int i= 0; i < bullets.size(); i++) {
		bullets.get(i).move();
		if (bullets.get(i).gety() > SCREENHEIGHT) {
			bullets.remove(i);
		}
	}
    }
    public void DeleteBullets() {
	for (int i= 0; i < bullets.size(); i++) {
		if (bullets.get(i).getdx2() < 0.2 || bullets.get(i).getdy2() < 0.2) {
			bullets.remove(i);
		}
	}
    }
    public void DrawFriendlyBullets(Graphics2D g2d) {
	for (int i= 0; i < friendlybullets.size(); i++) 
		DrawBullet(g2d, friendlybullets.get(i));
    }
    public void MoveFriendlyBullets() {
	for (int i= 0; i < friendlybullets.size(); i++) 
		friendlybullets.get(i).move();
    }

    public void DoCollision(Graphics2D g2d) {
	boolean flag = false;
	for (int i= 0; i < enemies.size(); i++) 
		for (int j= 0; j < friendlybullets.size(); j++) 
			if (friendlybullets.get(j).collision(enemies.get(i),mapx)) {
				friendlybullets.remove(j);
				DrawExplosion(g2d, enemies.get(i).getx()-(int)mapx,enemies.get(i).gety());
				int ret = enemies.get(i).hit(player);
				if (ret == 0) 
					enemies.remove(i);
				else if (ret == -1) {//NOTE: 1st powerup
					enemies.remove(i);
					player = new PlayerLevel1Powerup1(player.getx(),player.gety());
					player.setFriendlyBullets(friendlybullets);
				} else if (ret == -2) {//NOTE: fly under
					spritecount--;//NOTE
					enemies.remove(i);
					flag = true;
				}
			}
	if (flag) {
		levelstate.setData(enemies,sprites,aiengine,room,codecs,spritecount);
	}
    }

    public void DoCollisionPlayer() {
	for (int i= 0; i < enemies.size(); i++) 
		if (player.collision(enemies.get(i))) {
			enemies.remove(i);
		}
	for (int i= 0; i < bullets.size(); i++) 
		if (player.collision(bullets.get(i))) {
			bullets.remove(i);
		}
    }

    public int CollisionLadderLevel2() {
	if (mapx > 1350 && player.gety() < 250) {
		System.out.println("**********mapx="+mapx);
		return 1;
	} else {
		return 0;
	}
    }
    public int CollisionLadderLevel2ToLevel3() {
	if (player.gety() < 10) {
		System.out.println("Loading level 3 (2.2)");
		return 1;
	} else {
		return 0;
	}
    }
    public void DoCollisionPlayerLevel2() {
	for (int i= 0; i < enemies.size(); i++) 
		if (((PlayerLevel2)player).collisionLevel2(enemies.get(i),(int)mapx)) {
			enemies.remove(i);
		}
	for (int i= 0; i < bullets.size(); i++) 
		if (((PlayerLevel2)player).collisionLevel2(bullets.get(i),(int)mapx)) {
			bullets.remove(i);
		}
    }
    public void DoCollisionPlayerLevel3() {
	for (int i= 0; i < enemies.size(); i++) 
		if (((PlayerLevel3)player).collisionLevel3(enemies.get(i),(int)mapx)) {
			enemies.remove(i);
		}
	for (int i= 0; i < bullets.size(); i++) 
		if (((PlayerLevel3)player).collisionLevel3(bullets.get(i),(int)mapx)) {
			bullets.remove(i);
		}
    }


    public void DrawExplosion(Graphics2D g2d, int xx,int yy) {
        g2d.drawImage(explosion1, xx, yy, this);
    }
    public void DrawBackground(Graphics2D g2d) {
        g2d.drawImage(bg1, 0, (int)activationPixel, this);
    }
    /*public void DrawBackground4(Graphics2D g2d) {
        g2d.drawImage(bg4, (int)activationPixel, 0, this);
    }*/
    public void DrawBackground2(Graphics2D g2d) {
        g2d.drawImage(bg2, (int)(-mapx), 0, this);
    }
    public void DrawBackground3(Graphics2D g2d) {
        g2d.drawImage(bg3, (int)(-mapx), 0, this);
    }
    public void DrawMapUp(Graphics2D g2d) {
        int i = 0;
        int x, y;
        for (y = 0+(int)mapy; y < maph+(int)mapy+1; y++) {
            for (x = 0; x < mapw; x++) {
//                g2d.setColor(mazecolor);
                g2d.setStroke(new BasicStroke(2));

                if (leveldata[y*mapw+x] == 0) // draws left
                {
            		//nothing g2d.drawImage(tile1, x*60, i*60 + (int)activationPixel%60 , this);
                }
                else if (leveldata[y*mapw+x] == 1) // draws left
                {
            		g2d.drawImage(tile1, x*60, i*60 + (int)activationPixel%60 , this);
                }
                else if (leveldata[y*mapw+x] == 2) // draws left
                {
            		g2d.drawImage(tile2, x*60, i*60 + (int)activationPixel%60 , this);
                }
            }
	i += 1;
        }
        activationPixel -= 1;
	if (activationPixel%60 == 0 && activationPixel < 0)
        	mapy += 1;
    }

    public void DrawMapRight(Graphics2D g2d) {
        int i = 0;
        int x, y;
//                g2d.setColor(mazecolor);
                g2d.setStroke(new BasicStroke(2));

        for (y = 0+(int)mapy; y < maph+(int)mapy+1; y++) {
            for (x = 0; x < mapw; x++) {
                if (leveldata2[y*mapw+x] == 0) // draws left
                {
            		//nothing g2d.drawImage(tile1, x*60, i*60 + (int)activationPixel%60 , this);
                }
                else if (leveldata2[y*mapw+x] == 1) // draws left
                {
            		g2d.drawImage(tile1, i*60 + (int)activationPixel%60 , x*60, this);
                }
            }
	i += 1;
        }
        activationPixel -= 1;
	if (activationPixel%60 == 0 && activationPixel < 0)
        	mapy += 1;
    }

    public void GameInit() {
        LevelInit();
    }


    public void LevelInit() {
        int i;
        for (i = 0; i < nrofblocks * nrofblocks; i++)
            screendata[i] = leveldata[i];

    }


    public void GetImages()
    {
      
      explosion1 = new ImageIcon(prefix+"explosion48x35-1.png").getImage();//prefix+"ghost.png")).getImage();
      tile1 = new ImageIcon(prefix+"tile60x60-1.png").getImage();//prefix+"ghost.png")).getImage();
      tile2 = new ImageIcon(prefix+"tile60x60-2.png").getImage();//prefix+"ghost.png")).getImage();
      bg1 = new ImageIcon(prefix+"bg800x1200-1.png").getImage();//prefix+"ghost.png")).getImage();
      //bg2 = new ImageIcon(prefix+"bg1200x800-2.png").getImage();//prefix+"ghost.png")).getImage();
      bg2 = new ImageIcon(prefix+"bg4000x600-3.png").getImage();//prefix+"ghost.png")).getImage();
      bg3 = new ImageIcon(prefix+"bg4000x600-4.png").getImage();//prefix+"ghost.png")).getImage();
      //player = new ImageIcon(Board.class.getResource("/Users/roguelord/java/2d/shooter/pics/ghost.png")).getImage();//prefix+"ghost.png")).getImage();

    }

    public void paint(Graphics g)
    {
      super.paint(g);

      Graphics2D g2d = (Graphics2D) g;

      g2d.setColor(Color.black);
      g2d.fillRect(0, 0, d.width, d.height);

      levelstate.eventloop(g2d); 

      if (levelnumber == 1) {
      DeleteBullets();
      player.move();
      EnemiesShoot(bullets);
      EnemiesShootEnemies(enemies);
      DrawBackground(g2d);
      DrawMapUp(g2d);
      DrawSprites(g2d);
      SpritesShoot(bullets);
      SpritesShootEnemies(enemies);
      MoveSprites();
      DrawFriendlyBullets(g2d);
      MoveFriendlyBullets();
      DrawBullets(g2d);
      MoveBullets();
      DrawEnemies(g2d);
      MoveEnemies();
      DrawPlayer(g2d);
      DrawCodecs(g2d);
      DoCollision(g2d); 
      DoCollisionPlayer(); 
      Toolkit.getDefaultToolkit().sync();
      g.dispose();
      }
      if (levelnumber == 2) {
      EnemiesShoot(bullets);
      EnemiesShootEnemies(enemies);
      player.move();
      ((PlayerLevel2)player).fall();
      DrawBackground2(g2d);
      DrawFriendlyBullets(g2d);
      MoveFriendlyBullets();
      DrawBulletsLevel2(g2d);
      MoveBulletsLevel2();
      DrawEnemies(g2d);
      MoveEnemiesLevel2();
      DrawPlayer(g2d);
      DoCollision(g2d); 
      DoCollisionPlayerLevel2(); 
      Toolkit.getDefaultToolkit().sync();
      g.dispose();

      }
      if (levelnumber == 3) {
      EnemiesShoot(bullets);
      EnemiesShootEnemies(enemies);
      player.move();
      ((PlayerLevel3)player).fall();
      DrawBackground3(g2d);
      DrawFriendlyBullets(g2d);
      MoveFriendlyBullets();
      DrawBulletsLevel2(g2d);
      MoveBulletsLevel2();
      DrawEnemies(g2d);
      MoveEnemiesLevel2();
      DrawPlayer(g2d);
      DoCollision(g2d); 
      DoCollisionPlayerLevel3(); 
      Toolkit.getDefaultToolkit().sync();
      g.dispose();
	}
      if (levelnumber == 4) {
      DeleteBullets();
      player.move();
      EnemiesShoot(bullets);
      EnemiesShootEnemies(enemies);
      DrawBackground2(g2d);
      DrawMapRight(g2d);
      DrawSprites(g2d);
      SpritesShoot(bullets);
      SpritesShootEnemies(enemies);
      MoveSprites();
      DrawFriendlyBullets(g2d);
      MoveFriendlyBullets();
      DrawBullets(g2d);
      MoveBullets();
      DrawEnemies(g2d);
      MoveEnemies();
      DrawPlayer(g2d);
      DrawCodecs(g2d);
      DoCollision(g2d); 
      DoCollisionPlayer(); 
      Toolkit.getDefaultToolkit().sync();
      g.dispose();
      
	}
    }

    class TAdapter extends KeyAdapter {
        public void keyReleased(KeyEvent e) {
        } 
      
        public void keyPressed(KeyEvent e) {

          int key = e.getKeyCode();

	   if (key == KeyEvent.VK_N) {

    		enemies.removeAll(enemies);
    		bullets.removeAll(bullets);
    		friendlybullets.removeAll(friendlybullets);
    		sprites.removeAll(sprites);
    		codecs.removeAll(codecs);
    		aiengine = new AIengine();

		playerstate = new AIPlayerStateMove(++levelnumber,0);
		player = playerstate.initPlayer(0,player.getx(),player.gety());
		player.setFriendlyBullets(friendlybullets);
    		levelstate = new LevelStateLevel(levelnumber);
		levelstate.setData(enemies,sprites,aiengine, 
					room, codecs,spritecount);
	        	
	   } else {
		player.setKey(key);
		playerstate.move(player);
		if (/*player.getx() >= 394 && FIXME1*/levelnumber == 2 && key != KeyEvent.VK_F)//FIXME 
		{
			if (key != KeyEvent.VK_UP && key != KeyEvent.VK_DOWN/*NOTE ladders*/) {
				if (CollisionLadderLevel2() != 1) {
					if (key == KeyEvent.VK_RIGHT) {
						mapx += 10.0;
						levelstate.setMapX(mapx);
					}
					else if (key == KeyEvent.VK_LEFT) {
						mapx -= 10.0;
						levelstate.setMapX(mapx);
					}
				}
			} else if (key == KeyEvent.VK_UP) {
				System.out.println("UP key pressed");
				if (CollisionLadderLevel2() == 1) {
				System.out.println("on ladder....");
					playerstate = new AIPlayerStateMove(levelnumber,4);
					player = playerstate.initPlayer(4,player.getx(),player.gety());
					player.setFriendlyBullets(friendlybullets);
				} 
				if (CollisionLadderLevel2ToLevel3() == 1) {
    					enemies.removeAll(enemies);
    					bullets.removeAll(bullets);
    					friendlybullets.removeAll(friendlybullets);
    					sprites.removeAll(sprites);
    					codecs.removeAll(codecs);
    					aiengine = new AIengine();
					playerstate = new AIPlayerStateMove(++levelnumber,0);
					player = playerstate.initPlayer(0,player.getx(),player.gety());
					player.setFriendlyBullets(friendlybullets);
    					levelstate = new LevelStateLevel(levelnumber);
					levelstate.setData(enemies,sprites,aiengine, 
					room, codecs,spritecount);
					levelstate.setMapX(0);
					mapx = 0;
				}	
			}
			levelstate.setMapX(mapx);
		}
		System.out.println("mapx="+mapx);
		if (mapx == 700-400 && player instanceof PlayerLevel2Fall1) {
			playerstate = new AIPlayerStateMove(levelnumber,0);
			player = playerstate.initPlayer(0,player.getx(),player.gety());
			player.setFriendlyBullets(friendlybullets);

		}
		else if ((mapx == 700-400 && player instanceof PlayerLevel2) 
			||
			(mapx == 1000-400 && player instanceof PlayerLevel2Fall2)) 
		{
			System.out.println("*****************foo");
			playerstate = new AIPlayerStateMove(levelnumber,1);
			player = playerstate.initPlayer(1,player.getx(),player.gety());
			player.setFriendlyBullets(friendlybullets);
		} 
		else if (mapx == 1000-400) 
		{
			playerstate = new AIPlayerStateMove(levelnumber,2);
			player = playerstate.initPlayer(2,player.getx(),player.gety());
			player.setFriendlyBullets(friendlybullets);
		} else if (mapx == 1300-400) 
		{
			System.out.println("baz");
			playerstate = new AIPlayerStateMove(levelnumber,3);
			player = playerstate.initPlayer(3,player.getx(),player.gety());
			player.setFriendlyBullets(friendlybullets);
		}
	  }
	  /* if (levelnumber == 2) {
	  	int foo = player.movePWithKeyLevel2(key);
      		if (foo > 0 && player.getx() >= 394) {
			mapx+=5.0;
      		}
	  	player.shootP(key, friendlybullets);
	  }*/
	}
	}
    public void actionPerformed(ActionEvent e) {
        repaint();  
    }

}
